package ctrl

/*******************************************************************************
Copyright:cloud
Author:cloudapex@126.com
Version:1.0
Date:2020-06-12
Description: api server
*******************************************************************************/
import (
	"context"
	"net/http"
	"service/conf"

	"time"

	"gitee.com/cloudapex/ulern/cto"
	"gitee.com/cloudapex/ulern/htp"
	"gitee.com/cloudapex/ulern/util"
	"github.com/gin-gonic/gin"
)

var Svr *server

func init() { Svr = cto.Install("MC_Serve", &server{}).(*server) }

type server struct {
	cto.ControlBase

	api      http.Server
	routers  []func(*gin.Engine)
	middlers []func(*gin.Engine)
}

func (this *server) HandleInit() {
	this.ControlBase.HandleInit()

	this.initRouter()

	this.startServer()
}
func (this *server) HandleTerm() {
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	if err := this.api.Shutdown(ctx); err != nil {
		this.Error("api shut err:%v", err)
	}

	this.ControlBase.HandleTerm()
}

// -------- public
func (this *server) RegistRouter(fun func(gr *gin.Engine)) {
	this.routers = append(this.routers, fun)
}
func (this *server) RegistMiddler(fun func(gr *gin.Engine)) {
	this.middlers = append(this.middlers, fun)
}

// ------------ internal
func (this *server) initRouter() {
	htp.Init(conf.Main.Listn().RunMode)

	r := gin.Default()
	this.api.Handler = r

	r.Use(htp.MH_Corss())
	r.Use(htp.MH_Heavier(500 * time.Millisecond))

	// regist middler
	for _, fun := range this.middlers {
		fun(r)
	}

	// regist router
	for _, fun := range this.routers {
		fun(r)
	}
}
func (this *server) startServer() {
	util.Log.Infov("Start api server...")

	this.api.Addr = conf.Main.ListenAddr()

	if tls := conf.Main.ListnTls(); !tls.Enable {
		go func() {
			if err := this.api.ListenAndServe(); err != nil && err != http.ErrServerClosed {
				this.Fatal("Gin run err:%v", err)
			}
		}()
	} else {
		go func() {
			err := this.api.ListenAndServeTLS(util.ExePathJoin(tls.CrtFile), util.ExePathJoin(tls.KeyFile))
			if err != nil && err != http.ErrServerClosed {
				this.Fatal("Gin runTLS err:%v", err)
			}
		}()
	}

	util.Log.Info("Start api server on listen addr:%q, ginMode:%q", conf.Main.ListenAddr(), conf.Main.Listn().RunMode)
}
